from line_algo import *
#from shape import *
import shape
from math import *
def subtract_points(p1, p2):
    return [p1[i] - p2[i] for i in len(p1)]

def dot(vec1, vec2):
    return sum([vec1[i]*vec2[i] for i in range(len(vec1))])

#the cross product of vec1 and vec2, note it returns |vec1 X vec2| = |vec1| |vec2| sin(theta), where theta is the angle
#between vec1 and vec2
def cross(vec1, vec2):
    return vec1[0] * vec2[1] - vec2[0] * vec1[1]

def normalize(p_vec):
    m = mag(p_vec)
    return [p_vec[0]/m, p_vec[1]/m]

def normalized_dot(p_vec1, p_vec2):
    return (p_vec1[0]*p_vec2[0] + p_vec1[1] * p_vec2[1])/(mag(p_vec1)*mag(p_vec2))

def angle(p_vec):
    angle = acos(normalized_dot(p_vec, [1, 0]))
    #if the y-coord of the vector is less than 0 than return 2pi - acos
    if p_vec[1] < 0:
        return 2*pi - angle 
    return angle 


#returns true if sin(theta) >= 0 where theta is the angle between vec1 and vec2.
#i.e. theta > 0 if vec1 is clockwise relative to vec2
#where 0 <= angle <=2 * pi
def vec1_before_vec2(vec1, vec2):
    #the sign of cross product of vec1 and vec2 indicates if vec1 is clockwise relative to vec2.
    return vec1[0] * vec2[1] - vec2[0] * vec1[1] >= 0

def quadrant(vec):
    if vec[0] >= 0 and vec[1] >=0: return 0
    elif vec[0] < 0 and vec[1] >= 0: return 1
    elif vec[0] <= 0 and vec[1] < 0: return 2
    elif vec[0] > 0 and vec[1] < 0: return 3
    #Should never get to this point
    assert(False)

#sin_theta_positive = 1 if sin(theta) >= 0
#sin_theta_positive = -1 if sin(theta) < 0
def fast_rotate2d((x, y), cos_theta, sin_theta):
    new_x = cos_theta * x - sin_theta * y
    new_y = cos_theta * y + sin_theta * x
    return new_x, new_y

def rotate2d((x, y), p_angle):
    new_x = cos(p_angle) * x - sin(p_angle) * y
    new_y = cos(p_angle) * y + sin(p_angle) * x
    return (new_x, new_y)

def translate(segment, vec):
    point1 = ((segment[0])[0] + vec[0], (segment[0])[1] + vec[1])
    point2 = ((segment[1])[0] + vec[0], (segment[1])[1] + vec[1])
    return (point1, point2)

def translate_vertex(v, vec):
    (point, segments) = v
    p = point[0] + vec[0], point[1] + vec[1]
    for i in range(len(segments)):
        segments[i] = translate(segments[i], vec)
    return (p, segments)
    
def flip_vertex(vertex):
    (node, segments) = vertex
    n = (-node[0], node[1])
    segs = []
    for seg in segments:
        (n1, n2) = seg
        segs.append((flip_point(n1), flip_point(n2)))
    return (n, segs)

def flip_point(node):
    return (node[0], -node[1])

def scale_node(n, x_scale, y_scale):
    return n[0] * x_scale, n[1] * y_scale

def scale_vector(v, scale_x, scale_y):
    return v[0] * scale_x, v[1] * scale_y

def scale_vertex(vert, scale_x, scale_y):
    n = vert[0]
    new_n = scale_node(n, scale_x, scale_y)
    segs = vert[1]
    new_segs = []
    for n1, n2 in segs:
        new_segs.append((scale_node(n1, scale_x, scale_y), scale_node(n2, scale_x, scale_y)))
    return new_n, new_segs

def vertices(p_nodes, p_segments):
    """For each node return a list of line segments that touch that node"""
    vertices=[]
    for node in p_nodes:
        segments = []
        for segment in p_segments:
            if nodes_equal(node, segment[0]) or nodes_equal(node, segment[1]): segments.append(segment)
        vertices.append((node, segments))
    return vertices

def clamp_vertical_horizontal_lines(s):    
    segs  = s.line_segments
    new_segs = []
    for (n1, n2) in segs:
        #vertical line
        if(abs(n2[0] - n1[0]) <= EPSILON and abs(n2[1] - n1[1]) > EPSILON):
            m1 = (n1[0], n1[1])
            m2 = (n1[0], n2[1])
            new_segs.append((m1, m2))
            continue
        #horizontal line
        if(abs(n2[1] - n1[1]) <= EPSILON and abs(n2[0] - n1[0]) > EPSILON):
            m1 = (n1[0], n1[1])
            m2 = (n2[0], n1[1])
            new_segs.append((m1, m2))
            continue
        new_segs.append((n1, n2))
    return shape.shape('', '', segs)
